﻿#light
namespace FunctionalStructures
    type 'a LazyListCell = Nil | Cons of 'a * 'a LazyList
    and 'a LazyList = Lazy<'a LazyListCell>
        
    module Lazy = 
        let force (x: Lazy<'T>) = x.Force()

    module LazyList =
        let Add value list = lazy(Cons(value, list))

        let Empty<'a> = lazy(LazyListCell<'a>.Nil)

        let IsEmpty lazyList =  match lazyList with Lazy(Nil) -> true | _ -> false
        
        let rec Concat<'a> (list1:'a LazyList) (list2: 'a LazyList) = 
            match list1 with 
                | Lazy(Nil) -> list2
                | Lazy(Cons(head, tail)) -> lazy(Cons(head, Concat tail list2))

        let Reverse list = 
            let rec rev l1 l2 = 
                match l1 with
                    | Lazy(Nil) -> l2
                    | Lazy(Cons(x, s)) -> rev s (lazy(Cons(x, l2)))
            rev list (lazy(Nil))

        let Head list =
            match list with 
                | Lazy(Nil) -> failwith "empty"
                | Lazy(Cons(a,b)) -> a
            
        let Tail list =
            match list with 
                | Lazy(Nil) -> failwith "empty"
                | Lazy(Cons(a,b)) -> b

        